#pragma once
#include <pthread.h>

// 前向声明命名空间及类
namespace CondModule {
    class Cond;
}

namespace MutexModule
{
    class Mutex
    {
    public:
        enum Type
        {
            NORMAL = PTHREAD_MUTEX_NORMAL, // 普通锁
            RECURSIVE = PTHREAD_MUTEX_RECURSIVE, // 递归锁
            ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK, // 错误检查锁
            DEFAULT = PTHREAD_MUTEX_DEFAULT // 默认锁
        };
        Mutex(const enum Type type = DEFAULT)
        {
            pthread_mutexattr_t attr;
            pthread_mutexattr_init(&attr);
            pthread_mutexattr_settype(&attr, type);
            pthread_mutex_init(&_mutex, &attr);  // 用属性初始化互斥量
            pthread_mutexattr_destroy(&attr);  // 销毁属性对象
        }
        Mutex operator=(Mutex) = delete;
        ~Mutex()
        {
            pthread_mutex_destroy(&_mutex);
        }

        int lock()
        {
            return pthread_mutex_lock(&_mutex);
        }
        int trylock()
        {
            return pthread_mutex_trylock(&_mutex);
        }
        int timedlock(const timespec* time)
        {
            return pthread_mutex_timedlock(&_mutex, time);
        }
        int unlock()
        {
            return pthread_mutex_unlock(&_mutex);
        }
        
    private:
        friend class CondModule::Cond;
        pthread_mutex_t _mutex;
    };

    class LockGuard
    {
    public:
        LockGuard(Mutex& mutex) :_mutex(mutex)
        {
            _mutex.lock();
        }
        ~LockGuard()
        {
            _mutex.unlock();
        }
    private:
        Mutex& _mutex;
    };
}